home *** CD-ROM | disk | FTP | other *** search
/ Dr. Windows 3 / dr win3.zip / dr win3 / PROGRAMR / OLE2BOOK.ZIP / CHAP06.ZIP / CHAP06 / EDATAOBJ / EDATAOBJ.CPP < prev    next >
C/C++ Source or Header  |  1993-06-15  |  11KB  |  474 lines

  1. /*
  2.  * EDATAOBJ.CPP
  3.  *
  4.  * Data Object implemented in an application.  This object supports
  5.  * IUnknown and IDataObject interfaces.
  6.  *
  7.  * Copyright (c)1993 Microsoft Corporation, All Rights Reserved
  8.  *
  9.  * Kraig Brockschmidt, Software Design Engineer
  10.  * Microsoft Systems Developer Relations
  11.  *
  12.  * Internet  :  kraigb@microsoft.com
  13.  * Compuserve:  >INTERNET:kraigb@microsoft.com
  14.  */
  15.  
  16.  
  17. #define INITGUIDS
  18. #include <ole2ver.h>
  19. #include "edataobj.h"
  20.  
  21.  
  22.  
  23. //Count number of objects and number of locks.
  24. ULONG       g_cObj=0;
  25. ULONG       g_cLock=0;
  26.  
  27. //Make window handle global so other code can cause a shutdown
  28. HWND        g_hWnd=NULL;
  29. HINSTANCE   g_hInst=NULL;
  30.  
  31.  
  32.  
  33. /*
  34.  * WinMain
  35.  *
  36.  * Purpose:
  37.  *  Main entry point of application.
  38.  */
  39.  
  40. int PASCAL WinMain(HINSTANCE hInst, HINSTANCE hInstPrev
  41.     , LPSTR pszCmdLine, int nCmdShow)
  42.     {
  43.     MSG         msg;
  44.     LPAPPVARS   pAV;
  45.  
  46.    #ifndef WIN32
  47.     SetMessageQueue(96);
  48.    #endif
  49.  
  50.     g_hInst=hInst;
  51.  
  52.     //Create and initialize the application.
  53.     pAV=new CAppVars(hInst, hInstPrev, pszCmdLine, nCmdShow);
  54.  
  55.     if (NULL==pAV)
  56.         return -1;
  57.  
  58.     if (pAV->FInit())
  59.         {
  60.         while (GetMessage(&msg, NULL, 0,0 ))
  61.             {
  62.             TranslateMessage(&msg);
  63.             DispatchMessage(&msg);
  64.             }
  65.         }
  66.  
  67.     delete pAV;
  68.     return msg.wParam;
  69.     }
  70.  
  71.  
  72.  
  73.  
  74.  
  75.  
  76.  
  77. /*
  78.  * DataObjectWndProc
  79.  *
  80.  * Purpose:
  81.  *  Standard window class procedure.
  82.  */
  83.  
  84. LRESULT FAR PASCAL __export DataObjectWndProc(HWND hWnd, UINT iMsg
  85.     , WPARAM wParam, LPARAM lParam)
  86.     {
  87.     LPAPPVARS   pAV;
  88.  
  89.     //This will be valid for all messages except WM_NCCREATE
  90.     pAV=(LPAPPVARS)GetWindowLong(hWnd, DATAOBJWL_STRUCTURE);
  91.  
  92.     switch (iMsg)
  93.         {
  94.         case WM_NCCREATE:
  95.             //CreateWindow passed pAV to us.
  96.             pAV=(LPAPPVARS)((LONG)((LPCREATESTRUCT)lParam)->lpCreateParams);
  97.  
  98.             SetWindowLong(hWnd, DATAOBJWL_STRUCTURE, (LONG)pAV);
  99.             return (DefWindowProc(hWnd, iMsg, wParam, lParam));
  100.  
  101.         case WM_DESTROY:
  102.             PostQuitMessage(0);
  103.             break;
  104.  
  105.         default:
  106.             return (DefWindowProc(hWnd, iMsg, wParam, lParam));
  107.         }
  108.  
  109.     return 0L;
  110.     }
  111.  
  112.  
  113.  
  114.  
  115.  
  116. /*
  117.  * ObjectDestroyed
  118.  *
  119.  * Purpose:
  120.  *  Function for the DataObject object to call when it gets destroyed.
  121.  *  We destroy the main window if the proper conditions are met for
  122.  *  shutdown.
  123.  *
  124.  * Parameters:
  125.  *  None
  126.  *
  127.  * Return Value:
  128.  *  None
  129.  */
  130.  
  131. void FAR PASCAL ObjectDestroyed(void)
  132.     {
  133.     g_cObj--;
  134.  
  135.     //No more objects and no locks, shut the app down.
  136.     if (0==g_cObj && 0==g_cLock && IsWindow(g_hWnd))
  137.         PostMessage(g_hWnd, WM_CLOSE, 0, 0L);
  138.  
  139.     return;
  140.     }
  141.  
  142.  
  143.  
  144.  
  145. /*
  146.  * CAppVars::CAppVars
  147.  * CAppVars::~CAppVars
  148.  *
  149.  * Constructor Parameters:
  150.  *  hInst           HINSTANCE of the Application from WinMain
  151.  *  hInstPrev       HINSTANCE of a previous instance from WinMain
  152.  *  pszCmdLine      LPSTR of the command line.
  153.  *  nCmdShow        UINT specifying how to show the app window, from WinMain.
  154.  */
  155.  
  156. CAppVars::CAppVars(HINSTANCE hInst, HINSTANCE hInstPrev, LPSTR pszCmdLine
  157.     , UINT nCmdShow)
  158.     {
  159.     UINT        i;
  160.  
  161.     //Initialize WinMain parameter holders.
  162.     m_hInst     =hInst;
  163.     m_hInstPrev =hInstPrev;
  164.     m_pszCmdLine=pszCmdLine;
  165.     m_nCmdShow  =nCmdShow;
  166.  
  167.     m_hWnd=NULL;
  168.  
  169.     for (i=0; i < DOSIZE_CSIZES; i++)
  170.         {
  171.         m_rgdwRegCO[i]=0;
  172.         m_rgpIClassFactory[i]=NULL;
  173.         }
  174.  
  175.     m_fInitialized=FALSE;
  176.     return;
  177.     }
  178.  
  179.  
  180. CAppVars::~CAppVars(void)
  181.     {
  182.     UINT        i;
  183.  
  184.     //Revoke and destroy the class factories of all sizes
  185.     for (i=0; i < DOSIZE_CSIZES; i++)
  186.         {
  187.         if (0L!=m_rgdwRegCO[i])
  188.             CoRevokeClassObject(m_rgdwRegCO[i]);
  189.  
  190.         if (NULL!=m_rgpIClassFactory[i])
  191.             m_rgpIClassFactory[i]->Release();
  192.         }
  193.  
  194.     if (m_fInitialized)
  195.         CoUninitialize();
  196.  
  197.     return;
  198.     }
  199.  
  200.  
  201.  
  202.  
  203.  
  204.  
  205. /*
  206.  * CAppVars::FInit
  207.  *
  208.  * Purpose:
  209.  *  Initializes an CAppVars object by registering window classes,
  210.  *  creating the main window, and doing anything else prone to failure.
  211.  *  If this function fails the caller should guarantee that the destructor
  212.  *  is called.
  213.  *
  214.  * Parameters:
  215.  *  None
  216.  *
  217.  * Return Value:
  218.  *  BOOL            TRUE if successful, FALSE otherwise.
  219.  */
  220.  
  221. BOOL CAppVars::FInit(void)
  222.     {
  223.     WNDCLASS        wc;
  224.     HRESULT         hr, hr2, hr3;
  225.     DWORD           dwVer;
  226.     UINT            i;
  227.  
  228.     //Check command line for -Embedding
  229.     if (lstrcmpi(m_pszCmdLine, "-Embedding"))
  230.         return FALSE;
  231.  
  232.     dwVer=CoBuildVersion();
  233.  
  234.     if (rmm!=HIWORD(dwVer))
  235.         return FALSE;
  236.  
  237.     if (FAILED(CoInitialize(NULL)))
  238.         return FALSE;
  239.  
  240.     m_fInitialized=TRUE;
  241.  
  242.     if (!m_hInstPrev)
  243.         {
  244.         wc.style          = CS_HREDRAW | CS_VREDRAW;
  245.         wc.lpfnWndProc    = DataObjectWndProc;
  246.         wc.cbClsExtra     = 0;
  247.         wc.cbWndExtra     = CBWNDEXTRA;
  248.         wc.hInstance      = m_hInst;
  249.         wc.hIcon          = NULL;
  250.         wc.hCursor        = NULL;
  251.         wc.hbrBackground  = (HBRUSH)(COLOR_WINDOW + 1);
  252.         wc.lpszMenuName   = NULL;
  253.         wc.lpszClassName  = "DataObject";
  254.  
  255.         if (!RegisterClass(&wc))
  256.             return FALSE;
  257.         }
  258.  
  259.     m_hWnd=CreateWindow("DataObject", "DataObject", WS_OVERLAPPEDWINDOW
  260.         ,35, 35, 350, 250, NULL, NULL, m_hInst, this);
  261.  
  262.     if (NULL==m_hWnd)
  263.         return FALSE;
  264.  
  265.     g_hWnd=m_hWnd;
  266.  
  267.     /*
  268.      * This code supplies three different classes, one for each type
  269.      * of data object that handles a different size of data.  All the
  270.      * class factories share the same implementation, but their
  271.      * instantiations differ by the type passed in the constructor.
  272.      * When the class factories create objects, they pass that size
  273.      * to the CDataObject contstructor as well.
  274.      */
  275.  
  276.     for (i=0; i < DOSIZE_CSIZES; i++)
  277.         {
  278.         m_rgpIClassFactory[i]=(LPCLASSFACTORY)new CDataObjectClassFactory(i);
  279.  
  280.         if (NULL==m_rgpIClassFactory[i])
  281.             return FALSE;
  282.  
  283.         m_rgpIClassFactory[i]->AddRef();
  284.         }
  285.  
  286.     hr=CoRegisterClassObject(CLSID_DataObjectSmall, (LPUNKNOWN)m_rgpIClassFactory[0]
  287.         , CLSCTX_LOCAL_SERVER, REGCLS_MULTIPLEUSE, &m_rgdwRegCO[0]);
  288.  
  289.     hr2=CoRegisterClassObject(CLSID_DataObjectMedium, (LPUNKNOWN)m_rgpIClassFactory[1]
  290.         , CLSCTX_LOCAL_SERVER, REGCLS_MULTIPLEUSE, &m_rgdwRegCO[1]);
  291.  
  292.     hr3=CoRegisterClassObject(CLSID_DataObjectLarge, (LPUNKNOWN)m_rgpIClassFactory[2]
  293.         , CLSCTX_LOCAL_SERVER, REGCLS_MULTIPLEUSE, &m_rgdwRegCO[2]);
  294.  
  295.     if (FAILED(hr) || FAILED(hr2) || FAILED(hr3))
  296.         return FALSE;
  297.  
  298.     return TRUE;
  299.     }
  300.  
  301.  
  302.  
  303.  
  304.  
  305. /*
  306.  * CDataObjectClassFactory::CDataObjectClassFactory
  307.  * CDataObjectClassFactory::~CDataObjectClassFactory
  308.  *
  309.  * Constructor Parameters:
  310.  *  iSize           UINT specifying the data size for this class.
  311.  */
  312.  
  313. CDataObjectClassFactory::CDataObjectClassFactory(UINT iSize)
  314.     {
  315.     m_cRef=0L;
  316.     m_iSize=iSize;
  317.     return;
  318.     }
  319.  
  320.  
  321. CDataObjectClassFactory::~CDataObjectClassFactory(void)
  322.     {
  323.     return;
  324.     }
  325.  
  326.  
  327.  
  328.  
  329.  
  330.  
  331. /*
  332.  * CDataObjectClassFactory::QueryInterface
  333.  * CDataObjectClassFactory::AddRef
  334.  * CDataObjectClassFactory::Release
  335.  */
  336.  
  337. STDMETHODIMP CDataObjectClassFactory::QueryInterface(REFIID riid
  338.     , LPVOID FAR *ppv)
  339.     {
  340.     *ppv=NULL;
  341.  
  342.     //Any interface on this object is the object pointer.
  343.     if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_IClassFactory))
  344.         *ppv=(LPVOID)this;
  345.  
  346.     /*
  347.      * If we actually assign an interface to ppv we need to AddRef it
  348.      * since we're returning a new pointer.
  349.      */
  350.     if (NULL!=*ppv)
  351.         {
  352.         ((LPUNKNOWN)*ppv)->AddRef();
  353.         return NOERROR;
  354.         }
  355.  
  356.     return ResultFromScode(E_NOINTERFACE);
  357.     }
  358.  
  359.  
  360. STDMETHODIMP_(ULONG) CDataObjectClassFactory::AddRef(void)
  361.     {
  362.     return ++m_cRef;
  363.     }
  364.  
  365.  
  366. STDMETHODIMP_(ULONG) CDataObjectClassFactory::Release(void)
  367.